跳到主要内容

C# 的一些概念

参考资料 .NET Standard 2.0正式发布了 参考资料 官方资料 参考资料 .NET 中的程序集

前言

因为学习 C# 总是会被一些概念搞得晕头转向,所以这里专门用来整理一下

dot Net 的历史

学习 dotNet 之前先来看一下它的历史,从而能更好的了解 C#体系

Java平台.NET平台
开发语言JavaC#、VB.NET、Managed C++等
中间语言Java bytecodeCommon Intermediate Language(CIL)
运行时Java Virtual MachineCommon Language Runtime(CLR)

.NET Framework 最大的问题始终没有很好解决,那就是:跨平台问题。它只能运行于微软专属的 Windows 操作系统,这大大阻碍了其在服务器领域的普及,尽管有非官方支持的 Mono,但跨平台这个事情上面,它确实没法跟 Java相提并论。

在微软新一任 CEO纳德拉上台了之后,微软迅速调整了其发展策略,从过去的一切以 Windows 为中心的策略转移到“云”上,重点是考虑为用户提供怎样的服务,而不是提供怎样的操作系统。.NET Core 从此诞生。

.NET Core 的正式版1.0是在 2016年7月发布的

.NET Core 从功能上来看,是 .NET Framework 的子集,因为有些 Windows专属的东西(如涉及到 GUI 的 WPF)是没办法在 Linux 上实现的。

现在相当于出现了两个 .NET 平台(如果算上 Mono 的话就3个了),一个是传统的 Windows 上的 .NET Framework,它仍旧继续发展着,另一个是跨平台版的 .NET Core,功能略差,但却可以跨平台。

现在的问题是,我开发了一些库,到底是要用 .NET Framework 开发还是 .NET Core 开发呢?

源代码理论上来说都是相同的,但两个平台又确实存在着差异,于是一个标准应运而生,它紧接着 .NET Core 的步伐发布,这就是 .NET Standard

微软发话了:符合 .NET Standard标准的库,不管是 .NET Framework 还是 .NET Core 都能直接使用!

C# 的 DLL 是什么

用 C# 编写的源代码被编译成符合 CLI 规范的 中间语言 (IL) 就像 Java 编译出来的 class 文件之于 JVM 那样

实际上 C# 的 .dll 包含已编译的 IL 代码,.jar 包含已编译的 .class/byte 代码文件,它们的作用都是差不多的

说他们不同点,大概就是 jar 能跨平台,dll 不能跨平台,jar 叫做程序包,dll 叫做动态链接库,jar 可以解压缩,dll 不行。

程序集的概念

程序集构成了 .NET 应用程序的部署、版本控制、重用、激活范围和安全权限的基本单元。

程序集是为协同工作而生成的类型和资源的集合,这些类型和资源构成了一个逻辑功能单元。 程序集采用可执行文件 (.exe) 或动态链接库文件 (.dll) 的形式,它是 .NET 应用程序的构建基块 。 它们向公共语言运行时提供了注意类型实现代码所需的信息。

说白了程序集就是 VS生成的那些 exe, dll,它在 .net 框架下可以被 CLR 加载并运行的一堆数据集(类似 java 中的 jar 包)。

注:什么是公共语言运行时(Common Language Runtime, CLR)?简单来说就是:公共语言运行时(CLR)是一套完整的、高级的虚拟机,它被设计为用来支持不同的编程语言,并支持它们之间的互操作。

.net 中 exe 与 dll 的区别就是 exe 有程序接入口,即 Main 函数

说白了程序集一堆数据集的集合,包括:类型元数据,IL代码,资源。

  • 程序集元数据:包含程序集的版本信息,安全信息,签名等。
  • 类型元数据:记录了程序集将引用了哪些类,用户自定义了哪些类,字段,数据类型等一系列信息
  • IL代码:MSIL,微软中间语言,微软跨语言的基础,我们自己写的 C# 代码都编译成 IL 代码,保存在程序集中,在被 CLR 加载后,由 JIT 调用 BCL,FTL 即时编译成机器码来让 CPU 运行。

公共语言运行时中的程序集

程序集向公共语言运行时提供了注意类型实现代码所需的信息。 对于运行时,类型不存在于程序集上下文之外。 程序集定义以下信息:

  • *公共语言运行时执行的代码。 请注意,每个程序集只能有一个入口点:DllMain、WinMain 或 Main。*
  • *安全边界。 程序集就是在其中请求和授予权限的单元。(一些签名之类的安全信息)*
  • *类型边界。 每一类型的标识均包括该类型所驻留的程序集的名称。 在一个程序集的范围中加载的称为 MyType 的类型不同于在另一个程序集范围中加载的称为 MyType 的类型。(实际上等效于 Java 的包名)*
  • *引用范围边界。 程序集清单包含用于解析类型和满足资源请求的元数据。 该清单指定要在程序集外公开的类型和资源,并枚举它所依赖的其他程序集。*
  • *版本边界。 程序集是公共语言运行时中无版本冲突的最小单元。 同一程序集中的所有类型和资源均会被版本化为一个单元。 程序集清单描述你为任何依赖项程序集所指定的版本依赖性。*
  • *部署单元。 当一个应用程序启动时,只有该应用程序最初调用的程序集必须存在。 其他程序集(例如,包含本地化资源或实用工具类的程序集)可以按需检索。 这样,应用在第一次下载时就会比较精简。*

添加对程序集的引用

必须添加对应用程序中的程序集的引用,才能使用该程序集。 引用程序集后,应用程序可以使用其名称空间的所有可访问类型、属性、方法和其他成员,就好像它们的代码是源文件的一部分一样。

.NET 类库中的大多数程序集都是自动引用的。 如果系统程序集不是自动引用的,则对于 .NET Core,可以添加对包含该程序集的 NuGet 包的引用。 请使用 Visual Studio 中的 NuGet 包管理器,或者将程序集的 <PackageReference> 元素添加到 .csproj.vbproj 项目 。 在 .NET Framework 中,可以通过在 Visual Studio 中使用“添加引用”对话框,或者通过使用 C# 或 Visual Basic 编译器的 -reference 命令行选项,添加对该程序集的引用。